home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / UTILITY1 / MSWSRC35.ZIP / MEM.CPP < prev    next >
C/C++ Source or Header  |  1993-08-28  |  4KB  |  188 lines

  1. /*
  2.  *      mem.c           logo memory management module           dvb 6/28/88
  3.  *
  4.  *    Copyright (C) 1989 The Regents of the University of California
  5.  *    This Software may be copied and distributed for educational,
  6.  *    research, and not for profit purposes provided that this
  7.  *    copyright and statement are included in all such copies.
  8.  */
  9.  
  10. #include "logo.h"
  11. #include "globals.h"
  12. #ifdef ibm
  13. #ifndef __ZTC__
  14. #include <alloc.h>
  15. #endif
  16. #endif
  17.  
  18. NODE **gcstack;
  19. NODE **gctop;
  20.  
  21. NODE *free_list = NIL;                /* global ptr to free node list */
  22. struct segment *segment_list = NULL;  /* global ptr to segment list */
  23.  
  24. NODETYPES nodetype(NODE *nd)
  25. {
  26.     if (nd == NIL) return (PNIL);
  27.     return((NODETYPES)nd->node_type);
  28. }
  29.  
  30. void setobject(NODE *nd, NODE *newobj)
  31. {
  32.     NODE *oldobj = getobject(nd);
  33.  
  34.     if (newobj != NIL) increfcnt(newobj);
  35.     if (oldobj != NIL && decrefcnt(oldobj) == 0)
  36.     gc(oldobj);
  37.     nd->n_obj = newobj;
  38. }
  39.  
  40. void setcar(NODE *nd, NODE *newcar)
  41. {
  42.     NODE *oldcar = car(nd);
  43.  
  44.     if (newcar != NIL) increfcnt(newcar);
  45.     if (oldcar != NIL && decrefcnt(oldcar) == 0)
  46.     gc(oldcar);
  47.     nd->n_car = newcar;
  48. }
  49.  
  50. void setcdr(NODE *nd, NODE *newcdr)
  51. {
  52.     NODE *oldcdr = cdr(nd);
  53.  
  54.     if (newcdr != NIL) increfcnt(newcdr);
  55.     if (oldcdr != NIL && decrefcnt(oldcdr) == 0)
  56.     gc(oldcdr);
  57.     nd->n_cdr = newcdr;
  58. }
  59.  
  60. NODE *_reref(NODE *proc_var, NODE *newval)
  61. {
  62.     if (newval != NIL) increfcnt(newval);
  63.     if (proc_var != NIL && decrefcnt(proc_var) == 0)
  64.     gc(proc_var);
  65.     return(newval);
  66. }
  67.  
  68. NODE *unref(NODE *ret_var)
  69. {
  70.     if (ret_var != NIL) decrefcnt(ret_var);
  71.     return(ret_var);
  72. }
  73.  
  74. void addseg()
  75. {
  76.     int p;
  77.     struct segment *newseg;
  78.  
  79. // remove for debugging leaks
  80.     memory_count++;
  81.     if (status_flag) update_status_memory();
  82.  
  83.     if ((newseg = (struct segment *) malloc((size_t)sizeof(struct segment)))
  84.         != NULL) {
  85.     newseg->next = segment_list;
  86.     segment_list = newseg;
  87.     for (p = 0; p < SEG_SIZE; p++) {
  88.         newseg->nodes[p].n_cdr = free_list;
  89.         free_list = &newseg->nodes[p];
  90.     }
  91.     }
  92. }
  93.  
  94. NODE *newnode(NODETYPES type)
  95. {
  96.     NODE *newnd;
  97.  
  98. // include for debugging leaks
  99. //    memory_count++;
  100. //    if (status_flag) update_status_memory();
  101.  
  102.     if ((newnd = free_list) == NIL) {
  103.     addseg();
  104.     if ((newnd = free_list) == NIL)
  105.         err_logo(OUT_OF_MEM, NIL);
  106.     }
  107.     free_list = cdr(newnd);
  108.     settype(newnd, type);
  109.     setrefcnt(newnd, 0);
  110.     newnd->n_car = NIL;
  111.     newnd->n_cdr = NIL;
  112.     newnd->n_obj = NIL;
  113.     return(newnd);
  114. }
  115.  
  116. NODE *cons(NODE *x, NODE *y)
  117. {
  118.     NODE *val = newnode(CONS);
  119.  
  120.     setcar(val, x);
  121.     setcdr(val, y);
  122.     return(val);
  123. }
  124.  
  125. void gc(NODE *nd)
  126. {
  127.     NODE *tcar, *tcdr, *tobj;
  128.     int i;
  129.     NODE **pp;
  130.  
  131.     for (;;) {
  132.     switch (nodetype(nd)) {
  133.         case PUNBOUND:
  134.         setrefcnt(nd,10000);    /* save some time */
  135.         case PNIL:
  136.         if (gctop == gcstack) return;
  137.                 nd = *--gctop;
  138.         continue;
  139.         case LINE:
  140.                 nd->n_obj = NIL;
  141.         case CONS:
  142.         case CASEOBJ:
  143.         case RUN_PARSE:
  144.         case QUOTE:
  145.         case COLON:
  146.         case TREE:
  147.         case CONT:
  148.         tcdr = cdr(nd);
  149.         tcar = car(nd);
  150.         tobj = getobject(nd);
  151.         break;
  152.         case ARRAY:
  153.         pp = getarrptr(nd);
  154.         i = getarrdim(nd);
  155.         while (--i >= 0) {
  156.             tobj = *pp++;
  157.             deref(tobj);
  158. //                    if (tobj != NIL && decrefcnt(tobj) == 0)
  159. //                       if (gctop < &gcstack[GCMAX])
  160. //                   *gctop++ = tcdr;
  161.         }
  162.         free((char *)getarrptr(nd));
  163.         tcar = tcdr = tobj = NIL;
  164.         break;
  165.         case STRING:
  166.         case BACKSLASH_STRING:
  167.         case VBAR_STRING:
  168.         if (getstrhead(nd) != NULL && decstrrefcnt(getstrhead(nd)) == 0)
  169.             free(getstrhead(nd));
  170.         default:
  171.         tcar = tcdr = tobj = NIL;
  172.     }
  173.     nd->n_cdr = free_list;
  174.     free_list = nd;
  175.     if (tcdr != NIL && decrefcnt(tcdr) == 0)
  176.         if (gctop < &gcstack[GCMAX])
  177.         *gctop++ = tcdr;
  178.     if (tcar != NIL && decrefcnt(tcar) == 0)
  179.         if (gctop < &gcstack[GCMAX])
  180.         *gctop++ = tcar;
  181.     if (tobj != NIL && decrefcnt(tobj) == 0)
  182.         if (gctop < &gcstack[GCMAX])
  183.         *gctop++ = tobj;
  184.     if (gctop == gcstack) return;
  185.     nd = *--gctop;
  186.     }
  187. }
  188.